﻿/****************************************************
     * 作    者：Leng
     * 邮    箱：2947672@qq.com
     * 文件名称：ItemComponentSystem
     * 创建时间：2021/7/17 星期六 21:50:43
     * 功    能：
*****************************************************/
using System;
using System.Collections.Generic;

namespace ET
{
    public class BagComponentAwakeSystem : AwakeSystem<BagComponent,UnitInfo>
    {
        public override void Awake(BagComponent self,UnitInfo unit)
        {
            self.InitBag(unit);
        }
    }

    public static class BagComponentSystem
    {
        /// <summary>
        /// 初始化背包
        /// </summary>
        /// <param name="self"></param>
        /// <param name="info"></param>
        public static void InitBag(this BagComponent self,UnitInfo info)
        {
            self.CurrSize = info.Bag.CurrSize;
            
            //清理物品
            //self.Items.Clear();
            self.Items = new List<Item>();
            
            //背包物品 1.加载物品
            for (int i = 0;i < info.Bag.Items.Count;i++)
            {
                Item item = DeSerializeItemInfo(info.Bag.Items[i]);
                self.Items.Add(item);
            }
        }

        /// <summary>
        /// 添加服务器返回的道具
        /// </summary>
        public static void AddItemInfo(this BagComponent self, List<NItemInfo> items)
        {
            //背包物品 1.加载物品
            for (int i = 0;i < items.Count;i++)
            {
                Item item = DeSerializeItemInfo(items[i]);
                self.Items.Add(item);
            }
        }

        /// <summary>
        /// 更新已修理装备
        /// </summary>
        public static void UpdateFixEquips(this BagComponent self, List<NItemInfo> equips)
        {
            for (int i = 0; i < equips.Count; i++)
            {
                for (int j = 0; j < self.Items.Count; j++)
                {
                    if (self.Items[j].ItemId == equips[i].ItemId)
                    {
                        self.Items[j].MaxEndurance = equips[i].MaxEndurance;
                        self.Items[j].CurrEndurance = equips[i].CurrEndurance;
                        break;
                    }
                }
                
            }
        }

        public static Item DeSerializeItemInfo(NItemInfo itemInfo)
        {
            if (itemInfo.ItemId <= 0)
            {
                return null;
            }
            Item item = ItemFactory.CreateItemFromRecord(itemInfo.ConfigId);
            item.ItemId = itemInfo.ItemId;
            item.ItemCount = itemInfo.ItemCount;
            item.CreateTime = itemInfo.CreateTime;
            item.CurrEndurance = itemInfo.CurrEndurance;
            item.MaxEndurance = itemInfo.MaxEndurance;
            item.OreQuality = itemInfo.OreQuality;
            item.IsLock = itemInfo.IsLock;
            return item;
        }

        public static NItemInfo DeserializeItem(this BagComponent self,Item item)
        {
            if (item.ItemId <= 0)
            {
                return null;
            }

            NItemInfo info = new NItemInfo()
            {
                ItemId = item.Id,
                ConfigId = item.ConfigId,
                ItemCount = item.ItemCount,
                CreateTime = item.CreateTime,
                CurrEndurance = item.CurrEndurance,
                MaxEndurance = item.MaxEndurance,
                OreQuality = item.OreQuality,
                IsLock = item.IsLock
                };
            return info;
        }
        
       
        public static List<Item> AddBagItem(this BagComponent self,int itemConfigId,int count)
        {
            List<Item> items = new List<Item>();
            Item item = null;
            int surplus = 0;
            Item resultItem = null;
            do
            {
                resultItem = (self.AddItem(itemConfigId, count, item, out surplus));
                items.Add(resultItem);
                count = surplus;
            } while (resultItem != null && surplus > 0);

            return items;
        }

        public static Item AddItem(this BagComponent self,int configId,int count,Item item, out int surplus)
        {
            surplus = 0;
            //item不为空需要直接放入一个物品格子。
            if (item != null && self.InventoryIsFull())
            {
                Log.Debug("背包已满，加入item失败");
                return null;
            }

            //传入的item=null,首先从背包中找一个未满的同类item.
            if (item == null)
            {
                List<Item> findItemsByItemConfigId = self.FindItemsByItemConfigId(configId);
                item = self.GetNoFullAndCanManyItemInList(findItemsByItemConfigId, count);
            }

            //背包中没有未满的同类item，则创建一个，创建之前检查一下有没有合适的位置/
            if (item == null)
            {
                if (self.InventoryIsFull())
                {
                    Log.Debug("背包已满，加入item失败");
                    return null;
                }
                

                item = ItemFactory.CreateItem(configId);
            }

            //可以增加的数量
            int canAddNum = item.Config.MaxNum - item.ItemCount;
            //99-100
            int thisTimeNum = canAddNum - count >= 0 ? count : canAddNum;
            //99-1
            surplus = count - thisTimeNum;

            item.AddNum(thisTimeNum);
            self.Items.Add(item);
            
            return item;
        }

        public static int RemoveItemsById(this BagComponent self, List<long> items)
        {
            Item item = null;
            int result = 0;
            for (int i = 0; i < items.Count; i++)
            {
                item = self.GetItem(items[i]);
                if (item.Config.ItemType == "Ore")
                    result += item.Config.SellPrice * item.OreQuality;
                else
                    result += item.Config.SellPrice * item.ItemCount;
                self.RemoveItem(items[i], item.ItemCount);
            }

            return result;
        }

        /// <summary>
        /// 移除物品
        /// </summary>
        /// <param name="self"></param>
        /// <param name="itemId">Item对象的Id</param>
        /// <param name="num">移除的数量</param>
        /// <returns></returns>
        public static bool RemoveItem(this BagComponent self, long itemId, int num)
        {
            //根据itemId找到item；
            Item item = self.GetItem(itemId);
            if (item == null)
            {
                return false;
            }


            if (item.ItemCount < num)
            {
                return false;
            }

            //更新item数量
            int countNum = item.AddNum(-num);
            if (countNum <= 0)
            {
                self.Items.Remove(item);
                item.Dispose();
            }

            return true;
        }

        public static bool InventoryIsFull(this BagComponent self)
        {
            return self.Items.Count >= self.CurrSize;
        }

        /// <summary>
        /// 根据id获取实体。
        /// </summary>
        /// <param name="self"></param>
        /// <param name="itemId"></param>
        /// <returns></returns>
        public static Item GetItem(this BagComponent self, long itemId)
        {
            for (int i = 0; i < self.Items.Count; i++)
            {
                if (self.Items[i] != null && self.Items[i].ItemId == itemId)
                    return self.Items[i];
            }

            return null;
        }


        /// <summary>
        /// 根据Item配置的id查询相关的Item集合
        /// </summary>
        /// <param name="self"></param>
        /// <param name="itemConfigId"></param>
        /// <returns></returns>
        public static List<Item> FindItemsByItemConfigId(this BagComponent self, long itemConfigId)
        {
            List<Item> result = new List<Item>();
            foreach (Item item in self.Items)
            {
                if (item == null)
                {
                    continue;
                }

                if (item.ConfigId == itemConfigId)
                {
                    result.Add(item);
                }
            }

            return result;
        }

        /// <summary>
        /// 从传入的item列表中找一个未满的可叠加item.
        /// </summary>
        /// <param name="self"></param>
        /// <param name="items"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public static Item GetNoFullAndCanManyItemInList(this BagComponent self, List<Item> items, int num)
        {
            foreach (Item item in items)
            {
                if (!item.CanMany())
                {
                    continue;
                }

                if (item.ItemCount + num <= item.Config.MaxNum)
                {
                    return item;
                }
            }

            return null;
        }

        public static bool LockBagItem(this BagComponent self, long itemId)
        {
            Item item = self.GetItem(itemId);
            if (item == null) return false;
            item.IsLock = !item.IsLock;
            return true;
        }

        public static Item GetBagItemByConfigId(this BagComponent self, Int32 configId)
        {
            return self.Items.Find(x => x.ConfigId == configId);
        }
        
        /// <summary>
        /// 获取未锁定装备列表
        /// </summary>
        public static List<Item> GetUnlockItems(this BagComponent self)
        {
            List<Item> result = new List<Item>();
            //获取未锁定物品
            for (int i = 0; i < self.Items.Count; i++)
            {
                if(!self.Items[i].IsLock)
                    result.Add(self.Items[i]);
            }
            
            
            return self.RemoveEquipItems(result);
        }

        /// <summary>
        /// 获取可以维修装备列表
        /// </summary>
        public static List<Item> GetCanFixItems(this BagComponent self)
        {
            List<Item> result = new List<Item>();
            for (int i = 0; i < self.Items.Count; i++)
            {
                if(self.Items[i].Config.ItemType != "Equip") continue;;
                if (self.Items[i].Config.ItemLevel == "施法材料") continue;
                if(self.Items[i].CurrEndurance < self.Items[i].MaxEndurance)
                    result.Add(self.Items[i]);
            }

            return self.RemoveEquipItems(result);
        }

        /// <summary>
        /// 排除已装备物品
        /// </summary>
        public static List<Item> RemoveEquipItems(this BagComponent self,List<Item> items)
        {
            Item[] equipItems = self.GetParent<Unit>().GetComponent<EquipComponent>().Equips;
            //排除已装备物品
            for (int i = 0; i < equipItems.Length; i++)
            {
                if(equipItems[i] == null) continue;

                if (items.Contains(equipItems[i]))
                    items.Remove(equipItems[i]);
            }

            return items;
        }

        /// <summary>
        /// 修理装备
        /// </summary>
        public static List<Item> FixEquips(this BagComponent self, List<long> equips,bool normalFix)
        {
            List<Item> resultItems = new List<Item>();
            Item item = null;
            for (int i = 0; i < equips.Count; i++)
            {
                item = self.GetItem(equips[i]);
                if (normalFix)
                    self.CheckNormalFix(item);

                item.CurrEndurance = item.MaxEndurance;
                resultItems.Add(item);
            }

            return resultItems;
        }

        /// <summary>
        /// 随机获取普通修理耐久度减少
        /// </summary>
        public static void CheckNormalFix(this BagComponent self, Item item)
        {
            int i = RandomHelper.RandomNumber(0, 101);
            if (i < 10)
            {
                item.MaxEndurance -= 1;
            }
        }
    }
}
